iT邦幫忙

2024 iThome 鐵人賽

DAY 0
0
自我挑戰組

ASP.NET Core生成網站記錄系列 第 25

DAY25-裝飾器

  • 分享至 

  • xImage
  •  

如果你希望在多个类中使用日志功能,而不希望在每个类中重复编写日志的注入逻辑,可以考虑以下几种更简化的方法:

  1. 使用基类实现日志功能
    如果你有多个类都需要日志功能,可以创建一个基类,集中处理日志的注入。这样,其他类只需继承这个基类,而不需要自己实现日志的注入。

csharp
複製程式碼
public class BaseLogger
{
protected readonly ILogger _logger;

public BaseLogger(ILogger<BaseLogger> logger)
{
    _logger = logger;
}

// 你可以在这里添加通用的日志记录方法

}

public class DapperSql : BaseLogger
{
public DapperSql(ILogger logger) : base(logger)
{
// 其他初始化逻辑
}
}

public class z_sqlDepartments : DapperSql
{
public z_sqlDepartments(ILogger logger) : base(logger)
{
// 其他初始化逻辑
}
}
2. 使用装饰器模式
你可以创建一个日志装饰器,它在调用原始类方法之前和之后记录日志。这样,你只需对原始类进行包装,而不必修改原始类的实现。

csharp
複製程式碼
public class LoggingDecorator : IDapperSql
{
private readonly IDapperSql _inner;
private readonly ILogger<LoggingDecorator> _logger;

public LoggingDecorator(IDapperSql<TEntity> inner, ILogger<LoggingDecorator<TEntity>> logger)
{
    _inner = inner;
    _logger = logger;
}

public async Task DeleteAsync(int id)
{
    // 日志记录
    _logger.LogInformation($"Deleting record with ID: {id}");
    await _inner.DeleteAsync(id);
    _logger.LogInformation($"Successfully deleted record with ID: {id}");
}

// 其他 IDapperSql<TEntity> 方法实现

}
然后在 Program.cs 中注册装饰器:

csharp
複製程式碼
builder.Services.AddScoped(typeof(IDapperSql<>), typeof(LoggingDecorator<>));
3. 使用 AOP(面向切面编程)
使用 AOP,可以在不修改原始类代码的情况下添加日志记录。比如使用一些库(如 PostSharp 或 Castle DynamicProxy)来自动处理日志记录。

  1. 使用依赖注入和扩展方法
    你可以为你的项目创建扩展方法,将日志功能集中处理。

csharp
複製程式碼
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddDapperSqlWithLogging(this IServiceCollection services)
{
services.AddScoped(typeof(IDapperSql<>), typeof(DapperSql<>));
services.AddScoped(typeof(LoggingDecorator<>)); // 添加装饰器
return services;
}
}
在 Program.cs 中调用:

csharp
複製程式碼
builder.Services.AddDapperSqlWithLogging();

使用装饰器模式来实现日志记录功能,您可以按照以下步骤修改 DapperSql<TEntity> 类和装饰器类。这个过程将使日志记录逻辑从 DapperSql<TEntity> 中分离出来,简化其代码。

1. 创建装饰器类
首先,您需要创建一个装饰器类,它将实现与 DapperSql<TEntity> 相同的接口并包装其功能。这里是一个基本示例:

csharp
複製程式碼
public class DapperSqlLoggingDecorator<TEntity> : IDapperSql<TEntity> where TEntity : class
{
    private readonly IDapperSql<TEntity> _inner;
    private readonly ILogger<DapperSqlLoggingDecorator<TEntity>> _logger;

    public DapperSqlLoggingDecorator(IDapperSql<TEntity> inner, ILogger<DapperSqlLoggingDecorator<TEntity>> logger)
    {
        _inner = inner;
        _logger = logger;
    }

    public async Task DeleteAsync(int id)
    {
        _logger.LogInformation($"Attempting to delete record with ID: {id}");
        try
        {
            await _inner.DeleteAsync(id);
            _logger.LogInformation($"Successfully deleted record with ID: {id}");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Error occurred while trying to delete record with ID: {id}");
            throw;
        }
    }

    // 其他 IDapperSql<TEntity> 方法实现
    // 您需要在这里实现 DapperSql<TEntity> 接口的其他方法
}
2. 修改 DapperSql<TEntity>
然后,您可以简化 DapperSql<TEntity> 的构造函数,移除日志记录的相关代码:

csharp
複製程式碼
public class DapperSql<TEntity> : BaseClass, IDapperSql<TEntity> where TEntity : class
{
    public DapperRepository dpr { get; set; } = new DapperRepository();

    public TEntity EntityObject { get { return (TEntity)Activator.CreateInstance(typeof(TEntity)); } }
    public string EntityName { get { return typeof(TEntity).Name; } }

    // 其他方法不变...
}
3. 注册依赖项
在 Program.cs 中,您需要注册 DapperSql<TEntity> 和它的装饰器:

csharp
複製程式碼
builder.Services.AddScoped(typeof(IDapperSql<>), typeof(DapperSql<>));
builder.Services.Decorate(typeof(IDapperSql<>), typeof(DapperSqlLoggingDecorator<>));
使用 Decorate 方法需要确保您已引入必要的 NuGet 包(如 Scrutor),因为 .NET Core 默认不支持装饰器模式。

4. 使用装饰器
现在,您可以在需要使用 IDapperSql<TEntity> 的地方注入该接口。日志记录将自动应用于 DeleteAsync 方法和其他实现。

上一篇
DAY24-DapperSql問題
下一篇
DAY26-圖文編輯
系列文
ASP.NET Core生成網站記錄31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言